#include "kern/types.h"

#include "hs1_mmc_linux.h"
#include "regs_sdhci.h"
#include "io.h"

#include "stdio.h"


#define HS1_BASE 0x4A800000 

static void sdhci_dumpregs()
{
	printf(": =========== REGISTER DUMP (%s)===========\r\n", "hsmmc1");

	printf(": Sys addr: 0x%08x | Version:  0x%08x\r\n",
		readl(HS1_BASE + SDHCI_DMA_ADDRESS),
		readw(HS1_BASE + SDHCI_HOST_VERSION));
	printf(": Blk size: 0x%08x | Blk cnt:  0x%08x\r\n",
		readw(HS1_BASE + SDHCI_BLOCK_SIZE),
		readw(HS1_BASE + SDHCI_BLOCK_COUNT));
	printf(": Argument: 0x%08x | Trn mode: 0x%08x\r\n",
		readl(HS1_BASE + SDHCI_ARGUMENT),
		readw(HS1_BASE + SDHCI_TRANSFER_MODE));
	printf(": Present:  0x%08x | Host ctl: 0x%08x\r\n",
		readl(HS1_BASE + SDHCI_PRESENT_STATE),
		readb(HS1_BASE + SDHCI_HOST_CONTROL));
	printf(": Power:    0x%08x | Blk gap:  0x%08x\r\n",
		readb(HS1_BASE + SDHCI_POWER_CONTROL),
		readb(HS1_BASE + SDHCI_BLOCK_GAP_CONTROL));
	printf(": Wake-up:  0x%08x | Clock:    0x%08x\r\n",
		readb(HS1_BASE + SDHCI_WAKE_UP_CONTROL),
		readw(HS1_BASE + SDHCI_CLOCK_CONTROL));
	printf(": Timeout:  0x%08x | Int stat: 0x%08x\r\n",
		readb(HS1_BASE + SDHCI_TIMEOUT_CONTROL),
		readl(HS1_BASE + SDHCI_INT_STATUS));
	printf(": Int enab: 0x%08x | Sig enab: 0x%08x\r\n",
		readl(HS1_BASE + SDHCI_INT_ENABLE),
		readl(HS1_BASE + SDHCI_SIGNAL_ENABLE));
	printf(": AC12 err: 0x%08x | Slot int: 0x%08x\r\n",
		readw(HS1_BASE + SDHCI_ACMD12_ERR),
		readw(HS1_BASE + SDHCI_SLOT_INT_STATUS));
	printf(": Caps:     0x%08x | Caps_1:   0x%08x\r\n",
		readl(HS1_BASE + SDHCI_CAPABILITIES),
		readl(HS1_BASE + SDHCI_CAPABILITIES_1));
	printf(": Cmd:      0x%08x | Max curr: 0x%08x\r\n",
		readw(HS1_BASE + SDHCI_COMMAND),
		readl(HS1_BASE + SDHCI_MAX_CURRENT));
	printf(": Host ctl2: 0x%08x\r\n",
		readw(HS1_BASE + SDHCI_HOST_CONTROL2));

	printf(": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\r\n",
	       readl(HS1_BASE + SDHCI_ADMA_ERROR),
	       readl(HS1_BASE + SDHCI_ADMA_ADDRESS));

	printf(": ===========================================\r\n");
}


static void sdhci_s3c_set_clock(int clock)
{
	uint32_t ctrl;
    
    writew(0, HS1_BASE + SDHCI_CLOCK_CONTROL);
	ctrl = readl(HS1_BASE + S3C_SDHCI_CONTROL2);
	ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
	ctrl |= clock << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
	writel(ctrl, HS1_BASE + S3C_SDHCI_CONTROL2);    
}

static void sdhci_reset(uint8_t mask)
{
    unsigned long timeout;    
    writeb(mask, HS1_BASE + SDHCI_SOFTWARE_RESET);

    timeout = 100;
    while(readb(HS1_BASE + SDHCI_SOFTWARE_RESET) & mask)
    {
        if(timeout == 0)
        {
			printf("%s: Reset 0x%x never completed.\r\n", (int)mask);          
        }
    }
}

int sdhci_s3c_init()
{
    sdhci_reset(SDHCI_SOFTWARE_RESET);
    sdhci_dumpregs();
}

